#pragma once
#ifndef __SHADERBUFFERDATA_H__
#define __SHADERBUFFERDATA_H__

#include "Utility.h"

#include "../util/D3DCommon.h"
#include "../util/PreDeclare.h"

#include <vector>
#include <unordered_map>
#include <string>
#include <memory>

namespace WindGE
{
	class WIND_CORE_API ConstantBufferData
	{
	public:
		struct Variable
		{
			Variable(unsigned int _offset, unsigned int _size) : offset(_offset), size(_size) {}
			~Variable() { offset = 0; size = 0; }
			
			unsigned int	offset;
			unsigned int	size;
		};

	public:
		ConstantBufferData(const std::string& name);
		~ConstantBufferData();

		void attach(const std::string& n, void* data, unsigned int size);

		void attach(const std::string& n, bool var);
		void attach(const std::string& n, int var);
		void attach(const std::string& n, unsigned int var);
		void attach(const std::string& n, float var);
		void attach(const std::string& n, const XMFLOAT2& var);
		void attach(const std::string& n, const XMFLOAT3& var);
		void attach(const std::string& n, const XMFLOAT4& var);
		void attach(const std::string& n, const XMFLOAT4X4& var);

		void attach(const std::string& n, const std::vector<int>& var);
		void attach(const std::string& n, const std::vector<unsigned int>& var);
		void attach(const std::string& n, const std::vector<float>& var);
		void attach(const std::string& n, const std::vector<XMFLOAT2>& var);
		void attach(const std::string& n, const std::vector<XMFLOAT3>& var);
		void attach(const std::string& n, const std::vector<XMFLOAT4>& var);
		void attach(const std::string& n, const std::vector<XMFLOAT4X4>& var);

		void set(const std::string& n, void* data, unsigned int size);

		void set(const std::string& n, bool var);
		void set(const std::string& n, int var);
		void set(const std::string& n, unsigned int var);
		void set(const std::string& n, float var);
		void set(const std::string& n, const XMFLOAT2& var);
		void set(const std::string& n, const XMFLOAT3& var);
		void set(const std::string& n, const XMFLOAT4& var);
		void set(const std::string& n, const XMFLOAT4X4& var);

		void set(const std::string& n, const std::vector<int>& var);
		void set(const std::string& n, const std::vector<unsigned int>& var);
		void set(const std::string& n, const std::vector<float>& var);
		void set(const std::string& n, const std::vector<XMFLOAT2>& var);
		void set(const std::string& n, const std::vector<XMFLOAT3>& var);
		void set(const std::string& n, const std::vector<XMFLOAT4>& var);
		void set(const std::string& n, const std::vector<XMFLOAT4X4>& var);

		inline void*				data() const { return data_; }
		inline const std::string&	name() const { return name_; }
		inline unsigned int			size() const { return size_; }

	private:
		std::string									name_;
		void*										data_;
		unsigned int								size_;
		std::unordered_map<std::string, Variable>	var_list_;
	};

}//end namespace WindGE

#endif	//__SHADERBUFFERDATA_H__
